package com.test.jdk8.demo2;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * @ClassName Lambda6
 * @Description TODO
 * @Author 维康
 * @Date 2018/7/10 11:00
 * @Version 1.0
 **/
public class Lambda6 {

    public static void main(String[] args){

        /*
        Stream 接口 重要！！！
        创建stream–通过of方法
        */
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 5);
        Stream<String> stringStream = Stream.of("taobao");

       /*
       创建stream–通过generator方法
        生成一个无限长度的Stream，其元素的生成是通过给定的Supplier（这个接口可以看成一个对象的工厂，
        每次调用返回一个给定类型的对象）
        */
        Stream.generate(new Supplier<Double>() {
            @Override
            public Double get() {
                return Math.random();
            }
        });
        Stream.generate(() -> Math.random());
        Stream.generate(Math::random);

        /*创建stream–通过iterate方法
        也是生成无限长度的Stream，和generator不同的是，其元素的生成是重复对给定的种子值(seed)调用用户指定函数来生成的。
        其中包含的元素可以认为是：seed，f(seed),f(f(seed))无限循环
        这段代码就是先获取一个无限长度的正整数集合的Stream，然后取出前10个打印。千万记住使用limit方法，
        不然会无限打印下去。*/
        Stream.iterate(1, item -> item + 1).limit(10).forEach(System.out::println);


        testParallelStream();

    }

    private static void testParallelStream(){
       /*
        下面的例子展示了是如何通过并行Stream来提升性能：
        首先我们创建一个没有重复元素的大表：
        */
        int max = 1000000;
        List<String> values = new ArrayList<>(max);
        for (int i = 0; i < max; i++) {
            UUID uuid = UUID.randomUUID();
            values.add(uuid.toString());
        }

        //然后我们计算一下排序这个Stream要耗时多久，
        //串行排序：
        long t0 = System.nanoTime();
        long count = values.stream().sorted().count();
        System.out.println(count);
        long t1 = System.nanoTime();
        long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
        System.out.println(String.format("sequential sort took: %d ms", millis));


        // 串行耗时: 899 ms
        //并行排序：

        long t3 = System.nanoTime();
        long count2 = values.parallelStream().sorted().count();
        System.out.println(count2);
        long t4 = System.nanoTime();
        long millis2 = TimeUnit.NANOSECONDS.toMillis(t4 - t3);
        System.out.println(String.format("parallel sort took: %d ms", millis2));
        // 并行排序耗时: 472 ms
        //上面两个代码几乎是一样的，但是并行版的快了50%之多，唯一需要做的改动就是将stream()改为parallelStream()；
    }

}
/*通过Collection子类获取Stream*/
interface Collection<E> extends Iterable<E> {
    //其他方法省略
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
}
